package com.search2.search;

import com.search2.search.Search.SearchTypeEnum;

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;

public class ViewResults extends Activity{

	//Keep track of which result we are viewing
	private int currentResult = 1;
	private int totalResults = 0;
	
	//Cursor for the returned results
	private Cursor mCountCursor;
	
	//Definitions for the touch swipe handling
	private static final int SWIPE_MIN_DISTANCE = 120;
	private static final int SWIPE_THRESHOLD_VELOCITY = 200;
	private GestureDetector mGestureDetector;
	
	public enum AnimTypeEnum { NONE, FROM_LEFT_PREVIOUS, FROM_RIGHT_NEXT };
		
	/***
	 * Called when the activity starts
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//Set the view to results layout
        setContentView(R.layout.results_layout);
                       
        //Resolve the Intent and retrieve the search criteria
        Bundle extras = getIntent().getExtras();
		String query = extras.getString(SearchDbAdapter.QUERY);		
		SearchTypeEnum type = SearchTypeEnum.valueOf(extras.getString(SearchDbAdapter.SEARCH_TYPE));					
			
		//Display the query at the top
		if(query != null) {
			TextView searchText =(TextView) findViewById(R.id.searchQueryTextView);
			searchText.setText(query);
		}
		
		//Record the start time for performance monitoring
		long startTime = System.currentTimeMillis();
	
		//Retrieve the application 
		SearchDbAdapter dbHelper = ((SearchDbAdapter)getApplication());
             
		//Actually perform the search - returns quickly as its lazy...
        switch(type) {
        case QUESTIONS:
        	mCountCursor = dbHelper.searchQuestions(query); 
        	break;
        case ANSWER_WHOLE:
        	mCountCursor = dbHelper.searchAnswersWholeWord(query); 
        	break;
        case ANSWER_TRIPLETS:
        	mCountCursor = dbHelper.searchAnswersFirstOrLastLetters(query);
        	break;
        }
        
        //Get the system to manage the contents of the cursor through
        //the activity life-cycle
        startManagingCursor(mCountCursor);
        
        //This is where the search actually happens, as the cursor is lazy
        //When it has returned the count we are ready to go...
        if(mCountCursor.getCount() > 0)
        {
        	//store the number of results
        	totalResults = mCountCursor.getCount();
        	//set the cursor to the first result
        	mCountCursor.moveToFirst();

        	//use the common method to set the rest of the fields
        	//For the first result we don't want to animate it in
        	updateView(AnimTypeEnum.NONE);              

        	//Set up the button listeners
        	Button previousButton = (Button) findViewById(R.id.previousButton);
        	previousButton.setOnClickListener(button_listener);
		
        	Button nextButton = (Button) findViewById(R.id.nextButton);
        	nextButton.setOnClickListener(button_listener);
        }
        else
        {
        	//set the numbers
    		TextView numbersText = (TextView) findViewById(R.id.resultNumberTextView);
            numbersText.setText("0/0"); 
        	
    		Button previousButton = (Button) findViewById(R.id.previousButton);
    		previousButton.setVisibility(android.view.View.INVISIBLE);
    		Button nextButton = (Button) findViewById(R.id.nextButton);
    		nextButton.setVisibility(android.view.View.INVISIBLE);
    		
        	//No results returned
        	Toast.makeText(this, "Search returned no results", Toast.LENGTH_LONG).show();
        	
        }
        
        //Display the query time
    	long stopTime = System.currentTimeMillis();
    	long runTime = stopTime - startTime;
		TextView timeText = (TextView) findViewById(R.id.timeTextView);
		timeText.setText(String.valueOf(runTime) + "ms"); 
        
    	//Set up the back button listener
    	Button backButton = (Button) findViewById(R.id.backButton);
    	backButton.setOnClickListener(button_listener);
    	
    	//Set up the gesture detector for touch swipe
    	mGestureDetector = new GestureDetector(this, new SimpleGestureListener());
	}
	
	/***
	 * Called after each movement of the cursor to display
	 * the questions, answers and counters
	 */
	private void updateView(AnimTypeEnum animationType) {
			
		//Find the flipper
		ViewFlipper flipper= (ViewFlipper) findViewById(R.id.resultsFlipper);   
		
		//If previous, the view will already exist, so set up the animations and
		//flip back to it
		if(animationType == AnimTypeEnum.FROM_LEFT_PREVIOUS)
		{
	        flipper.setOutAnimation(AnimationUtils.loadAnimation(flipper.getContext(), R.anim.slide_right_out));
	        flipper.setInAnimation(AnimationUtils.loadAnimation(flipper.getContext(), R.anim.slide_in_left));
	        flipper.showPrevious();
		} 
		else //FROM_RIGHT_NEXT
		{
			//If next we need to create the new view
			//Must set to false to ensure this child is parent-less
			View flipArea = getLayoutInflater().inflate(R.layout.results_flip_area, flipper,false);
		
			//set the question
	        int titleColumn = mCountCursor.getColumnIndex("Title");
	        String question = mCountCursor.getString(titleColumn);
			TextView questionText =(TextView) flipArea.findViewById(R.id.questionTextView);
			questionText.setText(question);
			
			//set the numbers
			TextView numbersText = (TextView) flipArea.findViewById(R.id.resultNumberTextView);
	        numbersText.setText(currentResult + "/" + totalResults);  	
	        
	        //Display the current set of answers     
	        int a1Column = mCountCursor.getColumnIndex("content1");
	        String a1 = mCountCursor.getString(a1Column);
			TextView a1Text =(TextView) flipArea.findViewById(R.id.answerTextView1);
			a1Text.setText(a1);
			
	        int a2Column = mCountCursor.getColumnIndex("content2");
	        String a2 = mCountCursor.getString(a2Column);
			TextView a2Text =(TextView) flipArea.findViewById(R.id.answerTextView2);
			a2Text.setText(a2);
			
	        int a3Column = mCountCursor.getColumnIndex("content3");
	        String a3 = mCountCursor.getString(a3Column);
			TextView a3Text =(TextView) flipArea.findViewById(R.id.answerTextView3);
			a3Text.setText(a3);
			
	        int a4Column = mCountCursor.getColumnIndex("content4");
	        String a4 = mCountCursor.getString(a4Column);
			TextView a4Text =(TextView) flipArea.findViewById(R.id.answerTextView4);
			a4Text.setText(a4);		               
	                
			//Set up the animations if FROM_RIGHT_NEXT - we dont want any if NONE
			if(animationType == AnimTypeEnum.FROM_RIGHT_NEXT)
			{
				flipper.setOutAnimation(AnimationUtils.loadAnimation(flipper.getContext(), R.anim.push_left_out));
				flipper.setInAnimation(AnimationUtils.loadAnimation(flipper.getContext(), R.anim.slide_left));
			}
	        //Add the new result view
			flipper.addView(flipArea,currentResult);
			//Flip to the new result view
	        flipper.showNext();
		}
        
        //Enable/Disable the buttons as required
		Button previousButton = (Button) findViewById(R.id.previousButton);
		Button nextButton = (Button) findViewById(R.id.nextButton);
		//In this case there are previous entries, so enable the button
        if(currentResult > 1 ){
        	previousButton.setVisibility(android.view.View.VISIBLE);
        } else {
        	previousButton.setVisibility(android.view.View.INVISIBLE);
        }
        
        //If there are more entries then enable the button
        if(currentResult < totalResults){        	
        	nextButton.setVisibility(android.view.View.VISIBLE);
        } else {
        	nextButton.setVisibility(android.view.View.INVISIBLE);
        }
        
	}

	/***
	 * Move to the next result
	 */
	private void NextResult() {
		if(mCountCursor.moveToNext()) {	
			currentResult++;
			updateView(AnimTypeEnum.FROM_RIGHT_NEXT);
		}
	}
	
	/***
	 * Move to the previous result
	 */
	private void PreviousResult() {
		if(mCountCursor.moveToPrevious()) {
			currentResult--;
			updateView(AnimTypeEnum.FROM_LEFT_PREVIOUS);
		}
	}
	
	/***
	 * Button click handler
	 * Move to the next or previous question if possible, or finish the activity
	 */
    private OnClickListener button_listener = new OnClickListener() {
    	public void onClick(View v) {
    		Button b = (Button) v;
    		if(b.getId() == R.id.nextButton) {
    			NextResult();
    		} else if (b.getId() == R.id.previousButton) {
    			PreviousResult();
    		} else { //back button
    			//Finish the activity. Don't really need to set the result 
    			//as the Search activity does not make use of it, 
    			//but good practice too
    			setResult(RESULT_OK);
        		finish();
        		//Set up the animations we want when we return to the previous activity
        		overridePendingTransition(R.anim.slide_in_left,R.anim.slide_right_out);
    		}    		
    	}
    };

    /***
     * Called on touch event - pass the event to the gesture detector
     */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if(mGestureDetector.onTouchEvent(event))
			return true;
		else
			return false;
	}
    
	/***
	 * Gesture detection. SimpleOnGestureListener only requires
	 * implementations of the gestures we are interested in
	 */
    class SimpleGestureListener extends GestureDetector.SimpleOnGestureListener {

		/***
		 * Fling is a DOWN, some MOVEs then an UP. We could of overriden
		 * dispatchTouchEvent(MotionEvent ev) in the ViewResults class, but
		 * then we would need to track the sequence of events ourselves. Here
		 * Android has worked out its a "fling", i.e. a swipe of a finger from
		 * one position to another.
		 */
    	@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, 
				float velocityX, float velocityY) {
			//Only do something if the swipe was long enough and fast enough
    		//Swipe of finger was from right to left
			if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
				NextResult();
				//We have consumed the event so return true
				return true;
			} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
				//Only do something if the swipe was long enough and fast enough
	    		//Swipe of finger was from left to right
				PreviousResult();
				//We have consumed the event so return true
				return true;
			}
			//We have not consumed the event so return false
			return false;
		}
    }
}
